//  Copyright (c) 2024 Huawei Technologies Co., Ltd.
//  openUBMC is licensed under Mulan PSL v2.
//  You can use this software according to the terms and conditions of the Mulan PSL v2.
//  You may obtain a copy of Mulan PSL v2 at:
//        #  http://license.coscl.org.cn/MulanPSL2
//  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
//  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
//  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//  See the Mulan PSL v2 for more details.
import { GraphicalConsoleItem, KVMData } from '@/model/Service/KVM-interface';
import { getDataType } from '@/utils/utils';

const keyMap: Readonly<Record<string, string>> = {
  autoCloseLocalDisplay: 'AutoCloseLocalDisplay',
  encryptionConfigurable: 'EncryptionConfigurable',
  encryptionEnabled: 'EncryptionEnabled',
  graphicalConsole: 'GraphicalConsole',
  localKvmEnabled: 'LocalKvmEnabled',
  sessionTimeoutMinutes: 'SessionTimeoutMinutes',
  visibleJavaKvm: 'VisibleJavaKvm',
  systemId: 'SystemId',
  port: 'Port',
  enabled: 'Enabled',
  activatedSessionsType: 'ActivatedSessionsType',
  persistentUSBConnectionEnabled: 'PersistentUSBConnectionEnabled',
  autoOSLockEnabled: 'AutoOSLockEnabled',
  autoOSLockType: 'AutoOSLockType',
  autoOSLockKey: 'AutoOSLockKey',
  disableKeyboardDuringBiosStartup: 'DisableKeyboardDuringBiosStartup',
  maximumNumberOfSessions: 'MaximumNumberOfSessions',
  numberOfActiveSessions: 'NumberOfActiveSessions',
};

// 不可修改的键
export const readonlyKey = [
  'activatedSessionsType',
  'maximumNumberOfSessions',
  'numberOfActiveSessions',
];

/**
 * 替换对象中的键，支持嵌套对象
 * @param obj 原始对象
 * @param customKeyMap 键名映射表，默认使用全局 keyMap
 * @returns 替换键后的新对象
 */
export function replaceKeys<T>(obj: T, customKeyMap?: Record<string, string>): T {
  const currentKeyMap = customKeyMap ?? keyMap;
  const dataType = getDataType(obj);

  // 处理数组类型
  if (dataType === 'Array') {
    return ((obj as unknown) as any[]).map(item => replaceKeys(item, currentKeyMap)) as T;
  }

  // 处理普通对象类型
  if (dataType === 'Object') {
    const result: Record<string, any> = {};

    for (const [key, value] of Object.entries(obj as Record<string, any>)) {
      const newKey = currentKeyMap[key] ?? key;
      result[newKey] = replaceKeys(value, currentKeyMap);
    }

    return result as T;
  }

  // 其他所有类型（包括 null, undefined, 基本类型, 特殊对象等）直接返回
  return obj;
}

// 默认的端口号
export const defaultPort1 = 2198;
export const defaultPort2 = 2298;

// 系统锁定方式
export const lockTypeCustom = 'Custom';
export const lockTypeWindow = 'Windows';

// 比较公共参数
const commonParam = [
  'autoCloseLocalDisplay',
  'encryptionEnabled',
  'localKvmEnabled',
  'sessionTimeoutMinutes',
] as const;

// 比较自定义参数
const customParams = [
  'systemId',
  'port',
  'enabled',
  'persistentUSBConnectionEnabled',
  'autoOSLockEnabled',
  'autoOSLockType',
  'autoOSLockKey',
  'disableKeyboardDuringBiosStartup',
] as const;

function safeCompare(val1: any, val2: any): boolean {
  try {
    return val1 === val2 || JSON.stringify(val1) === JSON.stringify(val2);
  } catch {
    return val1 === val2;
  }
}

interface ExtendedGraphicalConsoleItem extends GraphicalConsoleItem {
  [key: string]: any;
}

function compareGraphicalConsole(
  newArray: ExtendedGraphicalConsoleItem[],
  oldArray: ExtendedGraphicalConsoleItem[],
) :any {
  const result: any[] = [];
  const maxLength = Math.max(newArray.length, oldArray.length);

  for (let i = 0; i < maxLength; i++) {
    const newItem = newArray[i];
    const oldItem = oldArray[i];
    if (!newItem || !oldItem) {
      continue;
    }

    const diff: any = { systemId: newItem.systemId };
    let hasChange = false;

    customParams.forEach(key => {
      if (shouldUpdateKey(key, newItem, oldItem)) {
        diff[key] = newItem[key];
        hasChange = true;
      }
    });

    if (hasChange) {
      result.push(diff);
    }
  }

  return result;
}

// 提取的判断函数
function shouldUpdateKey(
  key: string, newItem: ExtendedGraphicalConsoleItem, oldItem: ExtendedGraphicalConsoleItem,
): boolean {
  const isAutoLockKey = key === 'autoOSLockKey';
  
  if (isAutoLockKey) {
    const shouldCompare = (!!newItem.autoOSLockEnabled && newItem.autoOSLockType === lockTypeCustom);
    return shouldCompare && !safeCompare(newItem[key], oldItem[key]);
  }
  
  return newItem[key] !== oldItem[key];
}

/**
 * 比较kvm配置变更点，只返回变更的配置
 */
export function compareKvmConfig<T extends KVMData = KVMData>(
  newObj: T,
  oldObj: T,
): Partial<T> | null {
  if (!(getDataType(newObj) === 'Object' && getDataType(oldObj) === 'Object')) {
    return null;
  }

  const res: any = {};
  let hasDiff = false;

  // 比较公共参数
  commonParam.forEach(key => {
    if (newObj[key] !== oldObj[key]) {
      res[key] = newObj[key];
      hasDiff = true;
    }
  });

  // 比较 graphicalConsole
  if (
    getDataType(newObj.graphicalConsole) === 'Array' &&
    getDataType(oldObj.graphicalConsole) === 'Array'
  ) {
    const consoleDiff = compareGraphicalConsole(newObj.graphicalConsole, oldObj.graphicalConsole);
    if (consoleDiff.length > 0) {
      res.graphicalConsole = consoleDiff;
      hasDiff = true;
    }
  }

  return hasDiff ? res : null;
}
